package com.txt;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.txt.domain.Book;
import com.txt.email.EmailService;
import com.txt.listener.ExcelReadListener;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sms4j.api.SmsBlend;
import org.dromara.sms4j.core.factory.SmsFactory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.*;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;

@Slf4j
@SpringBootTest
public class T2 {

    private Long all = 500L;
    private Lock lock = new ReentrantLock();
    private static List<Book> bookList;
    @Autowired
    EmailService emailService;



    //线程测试
    @SneakyThrows
    @Test
    public void threadFutureTest() {
        Thread thread1 = new Thread(() -> {
            System.out.println("Runable start...");
        }, "thread1");
        Thread thread2 = new Thread(new FutureTask<>(() -> {
            System.out.println("Callable start...");
            return "Callable end...";
        }), "thread2");
        thread1.start();
        thread2.start();
    }

    //线程测试
    @SneakyThrows
    @Test
    public void timerTest() {
        Timer timer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("timerTask::" + LocalDateTime.now());
            }
        };
        long now = System.currentTimeMillis();
        Date thressAfter = new Date(now + 3000);
        timer.schedule(timerTask, thressAfter);
        Thread.sleep(3000);
    }

    //线程测试
    @SneakyThrows
    @Test
    public void scheduledThreadPoolExecutorTest() {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(2);
        Runnable runnable = () -> System.out.println(new Date());
        scheduledThreadPoolExecutor.schedule(runnable, 1000, TimeUnit.MILLISECONDS);
        scheduledThreadPoolExecutor.scheduleAtFixedRate(runnable, 0, 1000, TimeUnit.MILLISECONDS);
        Thread.sleep(3000);
    }

    //线程测试
    @SneakyThrows
    @Test
    public void completableFutureTest() {
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            return "supplyAsync";
        });
        CompletableFuture<String> exceptionallyCompletableFuture = completableFuture.exceptionally(e -> {
            System.out.println(e.getMessage());
            return "exceptionally";
        });
        String completableFutureRes = completableFuture.get();
        String exceptionallyRes = exceptionallyCompletableFuture.get();
        log.info(completableFutureRes);
        log.info(exceptionallyRes);
        completableFuture.thenRun(() -> System.out.println("thenRun start... " + new Date()));
        completableFuture.thenAccept(v -> System.out.println("thenAccept start... " + new Date()));
        completableFuture.thenApply(v -> "thenApply start... " + new Date());
        Thread.sleep(3000);
    }

    //模拟线程超卖问题
    @Test
    public void buyTest() {

        for (int i = 0; i < 100; i++) {
            new Thread(() -> buySynchronized(), "线程" + i).start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("buySynchronized->总剩余: " + all);


        for (int i = 0; i < 100; i++) {
            new Thread(() -> buyReentrantLock(), "线程" + i).start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("buyReentrantLock->总剩余: " + all);

        for (int i = 0; i < 100; i++) {
            new Thread(() -> buy(), "线程" + i).start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("buy->总剩余: " + all);

    }

    //IO文件测试 InputStream/outputStream
    @SneakyThrows
    @Test
    void IOTest() {
        String url = (String) System.getProperties().get("user.dir");
        String fileName = url + File.separator + "test.txt";
        File file = new File(fileName);

        String target = url + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "application.yml";

        InputStream inputStream = new FileInputStream(new File(target));
        OutputStream outputStream = new FileOutputStream(file);
        byte[] bytes = new byte[1024];
        int num = -1;
        while ((num = inputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, num));
            outputStream.write(bytes, 0, num);
        }
        inputStream.close();
        outputStream.close();
    }

    //bufferedWriter文件测试
    @SneakyThrows
    @Test
    void bufferedWriterTest() {
        String url = (String) System.getProperties().get("user.dir");
        String fileName = url + File.separator + "test.txt";
        student student = new student();
        student.setAge(1);
        student.setName("chenxin");
        String string = JSON.toJSON(student).toString();
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(fileName)));
        bufferedWriter.write(string);
        bufferedWriter.close();
    }

    //bufferedRead文件测试
    @SneakyThrows
    @Test
    void bufferedReaderTest() {

        String url = (String) System.getProperties().get("user.dir");
        String fileName = url + File.separator + "test.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(fileName)));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        bufferedReader.close();
    }

    //JSON测试
    @SneakyThrows
    @Test
    void fastJsonTest() {
        student student1 = new student().setAge(1).setName("chenxin");
        student student2 = new student().setAge(2).setName("fantao");
        student student3 = new student().setAge(3).setName("kecheng");
        List<student> studentList = List.of(student1, student2, student3);
        List<String> strings = studentList.stream().map(JSON::toJSONString).toList();
        String url = (String) System.getProperties().get("user.dir");
        String fileName = url + File.separator + "test.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(fileName)));
        for (int i = 0; i < strings.size(); i++) {
            bufferedWriter.write(strings.get(i));
            bufferedWriter.write("\n");
        }
        bufferedWriter.flush();
        bufferedWriter.close();

        BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(fileName)));
        List<student> sList = new ArrayList<>();
        while (true) {
            String line = null;
            line = bufferedReader.readLine();
            if (line == null)
                break;
            sList.add(JSON.parseObject(line, student.class));
        }
        sList.forEach(System.out::println);
    }

    //easyExcel测试
    @Test
    void easyExcelTest() {
        //写入到excel
        File excelFile = new File("D:\\ideaProject\\txt\\txt-admin\\test.xlsx");
        EasyExcel.write(excelFile, Book.class).sheet("txt").doWrite(bookList);
        //从excel中读数据
        ExcelReadListener<Book> bookDataListener = new ExcelReadListener();
        EasyExcel.read(excelFile, Book.class, bookDataListener).sheet().doRead();
        List<Book> books = bookDataListener.get();
        books.forEach(System.out::println);
    }

    //email测试
    @Test
    void emailTest() {

        emailService.sendText("测试邮件", "测试邮件内容", new String[]{"3085188206@qq.com"});
    }

   //短信测试
    @Test
    void smsMessageTest() {
        SmsBlend smsBlend = SmsFactory.getSmsBlend("case1");
        smsBlend.sendMessage("17790133525", new LinkedHashMap<>());
    }
   //randomTest
    @Test
    void randomTest() {
        Random random = new Random();
        int i = random.nextInt(9000) + 1000;
        System.out.println(i);
    }

    void buy() {
        try {
            Thread.sleep(3L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        all--;
        String name = Thread.currentThread().getName();
        System.out.println(name + "已经抢票一张,剩余: " + all);
    }

    void buySynchronized() {
        try {
            Thread.sleep(3L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        synchronized ("lock") {
            all--;
            String name = Thread.currentThread().getName();
            System.out.println(name + "已经抢票一张,剩余: " + all);
        }
    }

    void buyReentrantLock() {
        try {
            Thread.sleep(3L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        lock.lock();
        try {
            all--;
            String name = Thread.currentThread().getName();
            System.out.println(name + "已经抢票一张,剩余: " + all);
        } catch (Exception e) {
        } finally {
            lock.unlock();
        }
    }

    static {
        Book book1 = new Book();
        book1.setName("bookName1");
        book1.setAuthor("chenixn");
        book1.setPublish("publish");
        Book book2 = new Book();
        book2.setName("bookName2");
        book2.setAuthor("chenixn");
        book2.setPublish("publish");
        Book book3 = new Book();
        book3.setName("bookName3");
        book3.setAuthor("chenixn");
        book3.setPublish("publish");
        bookList = List.of(book1, book2, book3);
    }
}

